/****************************************************************************************************/
/************************************** Implementacion lista generica *******************************/


#include "liblista.h"


void crear_lista(lista *l){
    *l = NULL;
}

int insertar_nodo(lista *l, void *d){
    nodo *temp = (nodo *)malloc(sizeof(nodo));
    if(temp == NULL) return -1;
    
    temp->datos = d;
    temp->ant = NULL;
    
    if(*l == NULL)
        temp->sig = NULL;
    else{
        temp->sig = (*l);
        (*l)->ant = temp;
    }
    (*l) = temp;
    return 0;  
}

/*Borra los nodos de la lista que cumplan la condicion de la funcion comparadora*/
void borrar_nodo(lista* l, void *d, int(*compare_to)(void *, void *),void(*vacia_nodo)(void *)){
    lista aux = (*l);
    lista aux2;
    
    while(aux != NULL){
        if(compare_to(aux->datos,d)){
            if(*l == aux){
                (*l) = aux->sig;
                if(aux->sig != NULL)
                    aux->sig->ant = aux->ant;
            } else{
                if(aux->sig != NULL){
                    aux->sig->ant = aux->ant;
                }
                aux->ant->sig = aux->sig;
            }
            aux2 = aux;
            aux = aux->sig;
            vacia_nodo(aux2->datos);
            free(aux2);
        }else aux = aux->sig;
    }
}


void vaciar_lista(lista *l,void(*vacia_nodo)(void *) ){
    lista aux;
    while(*l != NULL){
        aux = *l;
        *l = (*l)->sig;
        vacia_nodo(aux->datos);
        free(aux);
    }
}

/*Muestra los nodos de la lista que cumplan la condicion de la funcion comparadora*/
void mostrar_nodos(lista *l,void *d,int(*compare_to)(void *, void *), void(*mostrar_nodo)(void *)) {
    lista aux = (*l);
    
    while(aux != NULL){
        if(compare_to(aux->datos,d))
            mostrar_nodo(aux->datos);
        aux = aux->sig;
    }
}



void mostrar_lista(lista *l, void(*mostrar_nodo)(void *)){
    lista aux = *l;
    
    while(aux != NULL){
        mostrar_nodo(aux->datos);
        aux = aux->sig;
    }
}
 
nodo * get_nodo_lista(lista *l,void *d,int(*compare_to)(void *, void *)){
    lista aux = (*l);
    
    while(aux != NULL){
        if(compare_to(aux->datos,d))
            return aux;
        aux = aux->sig;
    }
    return NULL;   
}

nodo * get_ultimo(lista *l){
	lista aux = (*l);
	
	while(aux->sig != NULL){
		aux = aux->sig;
	}
	return aux;
}

nodo * siguiente(nodo * n){
	return n->sig;
}

nodo * anterior(nodo * n){
	return n->ant;
}

void * get_datos(nodo *n){
    return n->datos;
}


